var neventbus = require("@native.eventbus")

function ThrowError(filename) {
    this.filename = filename;

    this.trace = function(funcname, line, type, message) {
        var error1_trace = "Js Traceback(most recent call last): \n";
        var error_file = "\tFile <" + this.filename + "> " + "line " + line + " <module>\n";
        var error_function = "\tFunction <" + funcname + "> '\n ";
        var error_message = "\t" + type + ":" + message + "\n";
        var message = error1_trace + error_file + error_function + error_message;
        console.log(message);
        return message;
    }
}

var __FILE__ = "eventbus.js";
var ERR = new ThrowError(__FILE__);

function EventBus(){
    this.listeners = {};

    this.getInstance = function(id) {
        return this.listeners[id]["instance"];
    }

    this.on = function(instance, event, callback){
        if(instance == undefined || event == undefined){
            ERR.trace("on", 30, "ERR_ARGS_INVALID","opt assert failed");
            return undefined;
        }

        var id = neventbus.id(instance);
        if(this.listeners[id] == undefined){
            this.listeners[id] = {};
        }

        this.listeners[id]["instance"] = instance;
        this.listeners[id][event] = callback;

        return id;
    }

    this.off = function(instance, event){
        if(instance == undefined || event == undefined){
            ERR.trace("off", 47, "ERR_ARGS_INVALID","opt assert failed");
            return undefined;
        }
        var id = neventbus.id(instance);
        delete this.listeners[id][event];
    }

    this.detach = function(instance){
        if(instance == undefined){
            ERR.trace("detach", 56, "ERR_ARGS_INVALID","opt assert failed");
            return undefined;
        }
        var id = neventbus.id(instance);
        delete this.listeners[id];
    }

    this.detachall = function (){
        this.listeners = {};
    }

    this.emit = function(id, event, args){

        if(id == undefined || event == undefined) {
            ERR.trace("emit", 70, "ERR_ARGS_TYPEERROR","opt assert failed");
            return undefined;
        }

        if(this.listeners[id] == undefined){
            ERR.trace("emit", 75, "ERR_ARGS_INVID","id not found");
            return undefined;
        }

        var callback = this.listeners[id][event];
        if(typeof(callback) == "function"){
            if(args != undefined){
                callback.apply(this.getInstance(id), args);
            }else{
                callback.apply(this.getInstance(id));
            }
        }
    }
}

globalThis.eventbus = new EventBus();
